﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using ScrumTable.Common;
using System.Windows.Data;
using System.Linq;

#endregion

namespace ScrumTable.UI.View.Converter
{

   
    /// <summary>
    /// ConverterAllowedValuesToElementMenuItems
    /// If there are to much items. This converter adds them at the front of the menu
    /// </summary>
    [ValueConversion(typeof(object), typeof(object))]
    public class ConverterAllowedValuesToElementMenuItems : IValueConverter
    {

        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------
        protected const int MaxElement = 8;
        protected readonly int[] MappingTo = { 1, 0, 2, 3, 4, 5, 7, 6 };
        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        public Predicate<object> FilterAction;
        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        public ConverterAllowedValuesToElementMenuItems()
        {
 
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------
        /// <summary>
        /// Converts a object into the target type
        /// </summary>
        /// <param name="value">The bool value produced by the binding source.</param>
        /// <param name="targetType">The type of the binding target property.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>
        /// </returns>
        public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            bool isList = value is IEnumerable;


            if (isList)
            {
                var list = ((IEnumerable)value).Cast<object>().ToList();
                if (list.Count == 0) { return value; }

                var newList = new object[8];
                list = GetFilteredList(list);
                //for each element at least one element
                int remains = list.Count() - MaxElement;

                int counterElement = 0;
                for (int i = 0; i < list.Count(); ++i)
                {
                    var item = list[i];
                    if (remains > 0)
                    {
                        var element = new ElementMenuHierarchical();
                        //add the first item
                        element.Element.Add(item);
                        //add other items
                        for (int u = 0; u < MaxElement - 1 && remains > 0; ++u)
                        {
                            ++i;
                            remains--;
                            item = list[i];
                            element.Element.Add(item);
                        }
                        element.Element = MapList(element.Element);
                        newList[counterElement] = element;

                        element.Value =
                            element.Element[Math.Min(element.Element.Count - 1, MappingTo[0])] +
                            Environment.NewLine + "-" + Environment.NewLine +
                            element.Element[Math.Min(element.Element.Count - 1, MappingTo[element.Element.Count - 1])];
                    }
                    else
                    {
                        newList[counterElement] = new ElementMenuHierarchical() { Value = item }; //item;    
                    }
                    counterElement++;
                }
                return (from item in MapList(newList) where item != null select item).ToList();
            }
            return value;
        }

        protected List<object> GetFilteredList(List<object> list)
        {
            if (FilterAction != null)
            {
                list = (from x in list where FilterAction(x) select x).ToList();
            }
            //max 64 elements
            if(list.Count>64)
            {
                list = list.GetRange(0, 64);
            }
            return list;
        }

        protected IList<object> MapList(IList<object> enumerable)
        {
            var newList = new object[8];
            for (int index = 0; index < enumerable.Count; ++index)
            {
                var item = enumerable[index];
                newList[MappingTo[index]] = item;
            }
            return (from item in newList where item != null select item).ToList();
        }


        /// <summary>
        /// Converts a object into the source type
        /// </summary>
        /// <param name="value">The bool value produced by the binding source.</param>
        /// <param name="targetType">The type of the binding target property.</param>
        /// <param name="parameter">The converter parameter to use.</param>
        /// <param name="culture">The culture to use in the converter.</param>
        /// <returns>
        /// </returns>
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;
        }
       
        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion

       
    }
    /// <summary>
    /// Contains hierarchical information
    /// </summary>
    public class ElementMenuHierarchical
    {
        /// <summary>
        /// all elements below this
        /// </summary>
        public IList<object> Element { get; set; }

        /// <summary>
        /// stored value for this element
        /// </summary>
        public object Value { get; set; }
    
        public ElementMenuHierarchical()
        {
            Element= new List<object>();
        }

        public override string ToString()
        {
            return Value.ToString();
        }
    }
}
